﻿using Autofac;
using Autofac.Core.Lifetime;
using AutoMapper;
using IoTAdapter.BaseCore.Enums;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using NLog.Config;
using SqlSugar;
using System.Drawing;
using System.Net.Http.Headers;
using Warehouse.Entites;
using Warehouse.IServices;
using Warehouse.IServices.Conveyorlines;
using Warehouse.IServices.TESinterface;
using Warehouse.Services.Repository;
using WCS.Entities;
using WCS.Entities.Api;
using WCS.Entities.BulkStorage;
using WCS.Entities.Enum;
using WCS.Entities.TES;
using WCS.IServices;
using WCS.ViewModels;
using WCS.ViewModels.AGVDTO;

namespace JuionWareHouse.Controllers
{
	[Route("api/[controller]/[action]")]
	[ApiController]
	public class PDAController : ControllerBase
	{

		private readonly Repository<Material> repositoryMaterial;
		private readonly Repository<SingleBox> repositorySingleBox;
		private readonly Repository<WareHouse> house;
		private readonly Repository<Binding> bind;
		private readonly ILifetimeScope lifetimeScope;
		private readonly IConveyorIServices Con;
		private readonly IDeviceManager _deviceManager;
		private readonly IStorageServices storageServices;
		private readonly Repository<Types> typ;
		private readonly Repository<MaterialClass> typeClass;
		private readonly IAGVSerive agv;
		public PDAController(Repository<WareHouse> house, Repository<Binding> bind, ILifetimeScope lifetimeScope, IConveyorIServices Con, IDeviceManager _deviceManager, Repository<Material> repositoryMaterial, Repository<SingleBox> repositorySingleBox,
			IStorageServices storageServices, Repository<Types> typ, Repository<MaterialClass> typeClass, IAGVSerive agv)
		{
			this.house = house;
			this.bind = bind;
			this.lifetimeScope = lifetimeScope;
			this.Con = Con;
			this._deviceManager = _deviceManager;
			this.repositoryMaterial = repositoryMaterial;
			this.repositorySingleBox = repositorySingleBox;
			this.storageServices = storageServices;
			this.typ = typ;
			this.typeClass = typeClass;
			this.agv = agv;
		}

		//备料
		[HttpPost]
		public async Task<ApiResult> PDArack(PDAMaterialViewModel model)
		{
			try
			{
				var ma= model.Palletnumber;
				var materia= repositoryMaterial.Query().Where(x=>x.Palletnumber==ma).FirstOrDefault();
                if (materia == null)
				{
                    // 操作容器,
                    using var db = lifetimeScope.BeginLifetimeScope().Resolve<ISqlSugarClient>().CopyNew();
                    if (model.Box.Count > 0)
                    {
                        model.Box.ForEach(x => x.MaterialName = model.MaterialName);
                        var isok = db.Insertable(model.Box).ExecuteCommand();
                        if (isok > 0)
                        {
							var earliesBoxTime = model.Box.OrderBy(x => x.Time).FirstOrDefault()?.Time;
							var material = new Material
							{
								Id = DateTime.Now.ToString("yyyyMMddHHmmss"),
								Palletnumber = model.Palletnumber,
								MaterialNumber = DateTime.Now.ToString("yyyyMMddHHmmss"),
								MaterialName = model.MaterialName,
								Specification = model.Specification,
								Voltage = model.Voltage,
								Color = model.Color,
								Grade = model.Grade,
								Number = model.Number,
								House = false,
								Productionline = "二期",
								EarliestBoxTime = earliesBoxTime ?? string.Empty
							};

                            var isok1 = db.Insertable(material).ExecuteCommand();
                            if (isok1 > 0)
                            {
                                var jobNumber = Convert.ToInt32(DateTime.Now.ToString("ddHHss"));
                                var job1 = await Con.Job1(jobNumber);
                                if (job1)
                                {
                                    await Con.Job2(jobNumber, 0);
                                }
                            }
                            if (material.Voltage != "" && material.Color != "" && material.Specification != "")
                            {
                                var types = new Types
                                {
                                    PalletNumber = material.Palletnumber,
                                    type = MaterialType.zhengtuo,
                                    JobNumbell = 123,
                                    NewJobNumbell = 0,
                                    MaterialNamber = material.MaterialNumber,
                                };
                                await db.Insertable(types).ExecuteCommandAsync();
                            }
                            else
                            {
                                var types = new Types
                                {
                                    PalletNumber = material.Palletnumber,
                                    type = MaterialType.two,
                                    JobNumbell = 123,
                                    NewJobNumbell = 0,
                                    MaterialNamber = material.MaterialNumber,
                                };
                                await db.Insertable(types).ExecuteCommandAsync();
                            }
                        }
                    }
                    //repositoryMaterial.Add(model);
                    return ApiResultHelp.Success($"添加成功,托盘号：{model.Palletnumber},物料名称：{model.MaterialName}");
                }
				else
				{
                    return ApiResultHelp.Error($"添加失败,托盘号已存在{model.Palletnumber}");
                }
			}
			catch (Exception ex)
			{
				return ApiResultHelp.Error(500, ex.Message);
			}
		}

		[HttpGet]
		//查询库内物料信息
		public ApiResult PDAHouse(string? Matename, string? Specification, string? Voltage, string? Grade, string? Color)
		{
			var list = repositoryMaterial.Query();
			return ApiResultHelp.Success(list);
		}
		/// <summary>
		/// 查找
		/// </summary>
		/// <param name="iMapper"></param>
		/// <param name="page">当前页码</param>
		/// <param name="limit">每页大小</param>
		/// <param name="query">筛选条件</param>
		/// <returns></returns>
		[HttpGet]
		public async Task<ApiResult> GetDevicesByPage(
			[FromServices] IMapper iMapper, 
			int page, 
			int limit, 
			[FromQuery] string? query)
		{
			RefAsync<int> total = 0;
			try
			{
				if (query != null)
				{
					JObject jobject = JObject.Parse(query);
					var models = new List<IConditionalModel>();
					foreach (var key in jobject.Properties())
					{
						if (string.IsNullOrEmpty(key.Value.ToString()))
							continue;
						if (key.Name == "type")
						{
							if (key.Value.ToString() != "None")
							{
								int index = (int)(EthernetDeviceVersion)Enum.Parse(typeof(EthernetDeviceVersion), key.Value.ToString());
								models.Add(new ConditionalModel()
								{ FieldName = key.Name, FieldValue = index.ToString(), ConditionalType = ConditionalType.Like });
							}
						}
                        if (key.Path.ToString() == "startDate")
                        {
                            models.Add(new ConditionalModel()
                            { FieldName = nameof(Material.EarliestBoxTime), FieldValue = key.Value.ToString(), ConditionalType = ConditionalType.GreaterThanOrEqual });
                            continue;
                        }
                        if (key.Path.ToString() == "endDate")
                        {
                            models.Add(new ConditionalModel()
                            { FieldName = nameof(Material.EarliestBoxTime), FieldValue = key.Value.ToString(), ConditionalType = ConditionalType.LessThanOrEqual });
                            continue;
                        }
                        else
						{
							models.Add(new ConditionalModel()
							{ FieldName = key.Name, FieldValue = key.Value.ToString(), ConditionalType = ConditionalType.Like });
						}
					}
					var materials = await repositoryMaterial.QueryAsync(models, page, limit, total);
					List<Material> materialList = iMapper.Map<List<Material>>(materials);
                    materialList.ForEach(x => x.StockAgeDays = CalcStockAgeDays(x));
                    return ApiResultHelp.Success(new { list = materialList, total = total.Value });
				}
				else
				{
					var materials = await repositoryMaterial.QueryAsync(page, limit, total);
					List<Material> materialList = iMapper.Map<List<Material>>(materials);
                    materialList.ForEach(x => x.StockAgeDays = CalcStockAgeDays(x));
                    return ApiResultHelp.Success(new { list = materialList, total = total.Value });
				}
			}
			catch (Exception ex)
			{
				return ApiResultHelp.Error($"查询出错:{ex.Message}");
			}
		}

        private static string CalcStockAgeDays(Material material)
        {
            if (string.IsNullOrWhiteSpace(material.EarliestBoxTime))
            {
                return string.Empty;
            }

            if (!DateTime.TryParse(material.EarliestBoxTime, out var outTime))
            {
                return string.Empty;
            }

            var days = (DateTime.Now.Date - outTime.Date).Days;

            return days.ToString();
        }

        //出库
        [HttpPost]
		public ApiResult PDAOut(PDAOutStorageViewModel pdaOutStorage)
		{
			try
			{
				var materialList = repositoryMaterial.Query();

				if (materialList.Count <= 0) return ApiResultHelp.Error($"出库失败，没有出库信息");
				var materialInfo = materialList.FirstOrDefault(i => i.MaterialName == pdaOutStorage.MaterialName
																	&& i.Specification == pdaOutStorage.Specification
																	&& i.Voltage == pdaOutStorage.Voltage && i.Grade == pdaOutStorage.Grade
																	&& i.Color == pdaOutStorage.Color && i.Number == pdaOutStorage.Number);
				if (materialInfo == null) return ApiResultHelp.Error($"出库失败，根据条件获取信息失败没有出库信息");

				// 从物料表中拿到库位Id和库位编号
				// 使用物料中存在的库位Id 去库位表中找到对应的库位信息
				var storageInfo = house.Query().FirstOrDefault(i => i.Id == Convert.ToInt32(materialInfo.StorageId));
				if (storageInfo == null) return ApiResultHelp.Error($"出库失败，根据物料信息中的库位Id没有找到库位信息");
				// 呼叫四向车
				var outStorageInfo = new OutStorageModel
				{
					MaterialNumber = storageInfo.MaterialNamber,
					location = pdaOutStorage.OutStoragePort,
					storageId = storageInfo.CrownPrincce
				}; 

				var isOk = storageServices.OutStorage(outStorageInfo);
				// 获取料口数据，调用叉车接口产生任务
				if (pdaOutStorage.OutStoragePort == "A")
				{
					var a = _deviceManager.Ports.FirstOrDefault(i => i.DeviceId == "11054");
					a?.BelongDevice.Operation.Write("132", (short)1);
					var res = a?.BelongDevice.Operation.ReadInt16("120");
					var numbell = Convert.ToInt32(DateTime.Now.ToString("yyyymmss"));
					if (res != null && res.Value == 1)
					{
						a?.BelongDevice.Operation.Write("122", (short)11053);
						a?.BelongDevice.Operation.Write("124", (short)numbell);
						var sty = new AGVchuDTO
						{
							portId = outStorageInfo.location,
							Content = ""
						};
						agv.occupyStation(sty);
					}
				}

				// 叉车返回成功则根据物料当前状态 （更新数据库）
				      

				// 并更新库位当前是否有货的状态 （更新数据库）
				  
				return ApiResultHelp.Success($"出库成功，出库物料号：{materialInfo.MaterialName}");
			}
			catch (Exception ex)
			{
				return ApiResultHelp.Error(500, ex.Message);
			}
		}

		//查询所有物料
		[HttpGet]
		public ApiResult Materialtypes()
		{
			var list = typeClass.Query();
			if (list != null)
			{
				return ApiResultHelp.Success("查询成功");
			}
			return ApiResultHelp.Error("查询失败");
		}

		[HttpPost]
		public ApiResult AGV(AGVchuDTO model)
		{
            agv.occupyStation(model);
			return ApiResultHelp.Success("成功");

        }

	}
}
